<template>
  <div :class="{ show: isShow }" class="header-search">
    <span id="guide-search" class="icon iconfont icon-sousuo" @click.stop="onShowClick"></span>
    <el-select
      ref="headerSearchSelectRef"
      class="header-search-select"
      v-model="search"
      filterable
      default-first-option
      remote
      placeholder="Search"
      :remote-method="querySearch"
      @change="onSelectChange"
    >
      <el-option
        v-for="option in searchOptions"
        :key="option.item.path"
        :label="option.item.title.join('>')"
        :value="option.item"
      ></el-option>
    </el-select>
  </div>
</template>

<script setup>
import { ref, computed, watch } from "vue";
import { filterRoutes } from "@/utils/route";
import { useRouter } from "vue-router";
//导入模糊搜索的库
import Fuse from "fuse.js";

import { generateRoutes } from "./FuseData.js";
import service from "@/utils/request.js";
import { watchSwitchLang } from "@/utils/i18n.js";

//搜索数据源
const router = useRouter();
let searchPool = computed(() => {
  //router.getRouts 获取所有的路由
  const routes = filterRoutes(router.getRoutes());
  return generateRoutes(routes);
});

//Fuse搜索库相关 Fuse数据接受两个参数 第一个是搜索的数据源 第二个参数是Fuse的一个配置对象
let fuse
const initFuse =searchPool=>{
   fuse = new Fuse(searchPool, {
  //是否按照优先级进行排序
  showldSort: true,
  //匹配长度超过这个值才会被认为是匹配的
  minMatchCharLength: 1,
  //将被搜索的键列表。这支持嵌套路径、加权搜索、在字符串和对象数组中搜索。
  // name:搜索的键
  // weight:对应的权重
  keys: [
    //这里对应的就是name是关键字 关键字为数据源中的title字段 权重是0.7 path是0.3
    { name: "title", weight: 0.7 },
    { name: "path", weight: 0.3 },
  ],
});
}

// 控制 search 输入框 显示
const isShow = ref(false);
const onShowClick = () => {
  isShow.value = !isShow.value;
};
initFuse(searchPool.value)

watch(isShow, (newVal) => {
  if (newVal) {
    headerSearchSelectRef.value.focus();
    document.body.addEventListener("click", onClose);
  } else {
    document.body.removeEventListener("click", onClose);
  }
});

// 关闭事件
const headerSearchSelectRef = ref(null);
const onClose = () => {
  search.value =''
  //让ref为headerSearchSelectRef的元素失去焦点
  headerSearchSelectRef.value.blur();
  //隐藏输入框
  isShow.value = false;
  // 清空下拉数据
  searchOptions.value = [];
};

// search 相关
const search = ref("");
// 搜索方法
const searchOptions = ref([]);
const querySearch = (query) => {
  if (query) {
    searchOptions.value = fuse.search(query);
  } else {
    searchOptions.value = [];
  }
};
// 选中下拉框的回调
const onSelectChange = (val) => {
  router.push(val.path);
  console.log("onSelectChange");
};

//执行utils中的监听语言变化的函数 当语言改变的时候重新计算数据源 处理国际化
watchSwitchLang(() => {
  searchPool = computed(() => {
    //router.getRouts 获取所有的路由
    const routes = filterRoutes(router.getRoutes());
    return generateRoutes(routes);
  });
  initFuse(searchPool.value)
});
</script>

<style lang="scss" scoped>
.header-search {
  font-size: 0 !important;
  .icon {
    font-size: 28px !important;
    cursor: pointer;
    font-size: 18px;
    vertical-align: middle;
  }
  .header-search-select {
    font-size: 18px;
    transition: width 0.4s;
    width: 0;
    overflow: hidden;
    background: transparent;
    border-radius: 0;
    display: inline-block;
    vertical-align: middle;

    ::v-deep .el-input__inner {
      border-radius: 0;
      border: 0;
      padding-left: 0;
      padding-right: 0;
      box-shadow: none !important;
      border-bottom: 1px solid #d9d9d9;
      vertical-align: middle;
    }
  }
  &.show {
    .header-search-select {
      width: 210px;
      margin-left: 10px;
    }
  }
}
</style>

